package com.wondertek.common.util.base;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.http.HttpStatus;
import cn.hutool.http.HttpUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.google.common.collect.Maps;
import com.wondertek.common.base.Result;
import com.wondertek.common.constant.SysConstant;
import com.wondertek.common.enums.SysLanguageEnum;
import com.wondertek.common.exception.AppException;
import com.wondertek.common.util.security.LoginUser;
import com.wondertek.common.util.security.SecurityUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.i18n.LocaleContextHolder;

import java.lang.reflect.Field;
import java.util.Locale;
import java.util.Map;

/**
 * @author: gongjiangtao
 * @date: 2024/7/31 11:04
 * @Description: 自定义http工具类
 * @Version: 1.0
 */
@Slf4j
public class HttpUtils {

    private static final int TIME_OUT = 5000;

    public static void main(String[] args) {
//        Test paramMap = new Test();
//        paramMap.setName("张三");
//        paramMap.setAge(1231);
//        Result<String> result = HttpUtils.get("http://1p36l59069.vicp.fun:54900/weizhang/backend/sys/auth/test", paramMap, String.class);
//        System.out.println(JSONUtil.toJsonStr(result));
    }

    /**
     * get请求
     *
     * @param url       地址
     * @param paramMap  参数
     * @param clazz     返回类
     * @return
     * @param <T>
     */
    public static <T> Result<T> get(String url, Map<String, Object> paramMap, Class<T> clazz) {
        log.info("http get 请求地址:{}, 请求参数: {}", url, JSONUtil.toJsonStr(paramMap));
        try {
            // 获取token
            Map<String, String> headerMap = addheaderMap();
            String response = HttpUtil.createGet(url).addHeaders(headerMap).timeout(TIME_OUT).form(paramMap).execute().body();
            log.info("http get 返回结果: {}", response);
            JSONObject jsonObject = JSONUtil.parseObj(response);
            Result<T> result = new Result<>();
            if (ObjectUtil.isEmpty(jsonObject) || !jsonObject.getBool("success") || HttpStatus.HTTP_OK != jsonObject.getInt("code")) {
                result.setData(null);
                result.setMessage(jsonObject.getStr("message"));
                result.setCode(jsonObject.getInt("code"));
                result.setSuccess(false);
                result.setTraceId(jsonObject.getStr("traceId"));
                return result;
            }
            result.setData(jsonObject.getBean("data", clazz));
            result.setMessage(jsonObject.getStr("message"));
            result.setCode(jsonObject.getInt("code"));
            result.setSuccess(true);
            result.setTraceId(jsonObject.getStr("traceId"));
            return result;
        } catch (Exception e) {
            log.error("get请求异常", e);
            throw new AppException("请求异常");
        }
    }


    /**
     * get请求
     *
     * @param url       地址
     * @param param     参数
     * @param clazz     返回类
     * @return
     * @param <T>
     */
    public static <T,P> Result<T> get(String url, P param, Class<T> clazz) {
        Map<String, Object> map = entityToMap(param);
        return get(url, map, clazz);
    }

    /**
     * Post请求
     *
     * @param url       地址
     * @param paramMap  参数
     * @param clazz     返回类
     * @return
     * @param <T>
     */
    public static <T> Result<T> post(String url, Map<String, Object> paramMap, Class<T> clazz) {
        log.info("http post 请求地址:{}, 请求参数: {}", url, JSONUtil.toJsonStr(paramMap));
        try {
            Map<String, String> headerMap = addheaderMap();
            String response = HttpUtil.createPost(url).addHeaders(headerMap).timeout(TIME_OUT).body(JSONUtil.toJsonStr(paramMap)).execute().body();
            log.info("http post 返回结果: {}", response);
            JSONObject jsonObject = JSONUtil.parseObj(response);
            Result<T> result = new Result<>();
            if (ObjectUtil.isEmpty(jsonObject) || !jsonObject.getBool("success") || HttpStatus.HTTP_OK != jsonObject.getInt("code")) {
                result.setData(null);
                result.setMessage(jsonObject.getStr("message"));
                result.setCode(jsonObject.getInt("code"));
                result.setSuccess(false);
                result.setTraceId(jsonObject.getStr("traceId"));
                return result;
            }
            result.setData(jsonObject.getBean("data", clazz));
            result.setMessage(jsonObject.getStr("message"));
            result.setCode(jsonObject.getInt("code"));
            result.setSuccess(true);
            result.setTraceId(jsonObject.getStr("traceId"));
            return result;
        } catch (Exception e) {
            log.error("post请求异常", e);
            throw new AppException("请求异常");
        }
    }

    /**
     * 添加请求头
     *
     * @return
     */
    private static Map<String, String> addheaderMap() {
        // 获取token
        LoginUser loginUser = SecurityUtil.SecurityContext.get();
        if(ObjectUtil.isEmpty(loginUser)){
            throw new AppException(HttpStatus.HTTP_UNAUTHORIZED, "token不存在或者失效");
        }
        Locale acceptLanguage = LocaleContextHolder.getLocale();
        Map<String,String> headerMap = Maps.newHashMap();
        headerMap.put(SysConstant.ACCEPTLANGUAGE, ObjectUtil.isEmpty(acceptLanguage) ? SysLanguageEnum.CHINESE.getCode() : acceptLanguage.toString());
        headerMap.put(SysConstant.AUTHORIZATION, loginUser.getToken());
        return headerMap;
    }


    /**
     * post请求
     *
     * @param url       地址
     * @param param     参数
     * @param clazz     返回类
     * @return
     * @param <T>
     */
    public static <T,P> Result<T> post(String url, P param, Class<T> clazz) {
        Map<String, Object> map = entityToMap(param);
        return post(url, map, clazz);
    }


    /**
     * 实体类转map
     *
     * @param paramEntity
     * @return
     * @param <P>
     */
    private static <P> Map<String, Object> entityToMap(P paramEntity) {
        Map<String, Object> paramMap = Maps.newHashMap();
        if (paramEntity != null) {
            Field[] fields = paramEntity.getClass().getDeclaredFields();
            for (Field field : fields) {
                field.setAccessible(true); // 访问 private 字段
                try {
                    Object value = field.get(paramEntity);
                    paramMap.put(field.getName(), value);
                } catch (Exception e) {
                    log.error("实体类转map异常", e);
                    throw new AppException("实体类转map异常");
                }
            }
        }
        return paramMap;
    }
}
